/*
Copyright (C) 2006-2007 The OZI Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the disclaimer that follows 
these conditions in the documentation and/or other materials 
provided with the distribution.
3. The name "OZI" must not be used to endorse or promote products
derived from this software without prior written permission.  For
written permission, please contact The OZI Project.
4. Products derived from this software may not be called "OZI", nor
may "OZI" appear in their name, without prior written permission
from The OZI Project.
In addition, we request (but do not require) that you include in the 
end-user documentation provided with the redistribution and/or in the 
software itself an acknowledgement equivalent to the following:
"This product includes software developed by The OZI Project."
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
This software consists of voluntary contributions made by many 
individuals on behalf of The OZI Project and was originally 
created by Matt Jezorek <mjezorek@bellsouth.net>.  
 */
package com.ozi.core;

import java.io.ByteArrayOutputStream;
import org.apache.log4j.Logger;

import com.ozi.utils.*;

/**
 *
 * @author <a href="http://oziproject.org">OZI Project Team</a>
 */
public class SIFMessage implements SIFObject {

    static final String PROTOCOL_VERSION = Configurator.get(Constants.PROTOCOL_VERSION);
    protected com.ozi.sif.objects.SIFMessage message = null;
    private static Logger log = Logger.getLogger(SIFMessage.class);

    public SIFMessage() {
        log.debug("Constructor");
        message = new com.ozi.sif.objects.SIFMessage();
        message.setVersion(PROTOCOL_VERSION);
    }

    public SIFMessage(Object sifObject) {
        log.debug("Constructor from SIFObject");
        new com.ozi.sif.objects.SIFMessage();
        setSIFObject(sifObject);
    }

    public Object getSIFObject() {
        return message;
    }

    public void setSIFObject(Object sif) {
        message = (com.ozi.sif.objects.SIFMessage) sif;
    }

    @Override
    public String toString() {
        String msg = null;
        try {
            OZIMarshaller ozim = OZIMarshaller.getInstance();
            ByteArrayOutputStream ops = new ByteArrayOutputStream();
            ozim.marshal(this, ops);
            msg = ozim.toString();
        } catch (Exception ex) {
            log.error(ex);
        }
        return msg;
    }

    /**
     * Returns the SIFAck internal to this message
     * @return
     */
    public final SIFAck getAck() {
        SIFAck ack = new SIFAck();
        ack.setSIFObject(message);
        return (ack);
    }

    /**
     * Returns the SIFPing internal to this message
     * @return
     */
    public SIFPing getPing() {
        SIFPing ping = new SIFPing();
        ping.setSIFObject(message);
        return (ping);
    }

    /**
     * Returns the SIFProvide internal to this message
     * @return
     */
    public SIFProvide getProvide() {
        SIFProvide provide = new SIFProvide();
        provide.setSIFObject(message);
        return (provide);
    }

    /**
     * Returns the SIFRegister internal to this message
     * @return
     */
    public SIFRegister getRegister() {
        SIFRegister register = new SIFRegister();
        register.setSIFObject(message);
        return (register);
    }

    /**
     * Returns the SIFRequest internal to this message
     * @return
     */
    public SIFRequest getRequest() {
        SIFRequest request = new SIFRequest();
        request.setSIFObject(message);
        return (request);
    }

    /**
     * Returns the SIFSleep internal to this message
     * @return
     */
    public SIFSleep getSleep() {
        SIFSleep sleep = new SIFSleep();
        sleep.setSIFObject(message);
        return (sleep);
    }

    /**
     * Returns the SIFSubscribe internal to this message
     * @return
     */
    public SIFSubscribe getSubscribe() {
        SIFSubscribe subscribe = new SIFSubscribe();
        subscribe.setSIFObject(message);
        return (subscribe);
    }

    /**
     * Returns the SIFUnprovide internal to this message
     * @return
     */
    public SIFUnprovide getUnprovide() {
        SIFUnprovide unprovide = new SIFUnprovide();
        unprovide.setSIFObject(message);
        return (unprovide);
    }

    /**
     * Returns the SIFUnregister internal to this message
     * @return
     */
    public SIFUnregister getUnregister() {
        SIFUnregister unregister = new SIFUnregister();
        unregister.setSIFObject(message);
        return (unregister);
    }

    /**
     * Returns the SIFUnsubscribe internal to this message
     * @return
     */
    public SIFUnsubscribe getUnsubscribe() {
        SIFUnsubscribe unsubscribe = new SIFUnsubscribe();
        unsubscribe.setSIFObject(message);
        return (unsubscribe);
    }

    /**
     * Returns the SIFWakeup internal to this message
     * @return
     */
    public SIFWakeup getWakeup() {
        SIFWakeup wakeup = new SIFWakeup();
        wakeup.setSIFObject(message);
        return (wakeup);
    }

    /**
     * Returns the SIFResponse internal to this message
     */
    public SIFResponse getResponse() {
        SIFResponse resp = new SIFResponse();
        resp.setSIFObject(message);
        return (resp);
    }

    /**
     * Returns a copy of the SIFHeader encapsulated in this message
     * @return the sif header or null if there's an error
     */
    public SIFHeader getHeader() {
        Class type = this.getClass();
        if (type == SIFAck.class) {
            return (new SIFHeader(this.message.getSIFAck().getSIFHeader()));
        } else if (type == SIFEvent.class) {
            return (new SIFHeader(this.message.getSIFEvent().getSIFHeader()));
        } else if (type == SIFProvide.class) {
            return (new SIFHeader(this.message.getSIFProvide().getSIFHeader()));
        } else if (type == SIFRegister.class) {
            return (new SIFHeader(this.message.getSIFRegister().getSIFHeader()));
        } else if (type == SIFRequest.class) {
            return (new SIFHeader(this.message.getSIFRequest().getSIFHeader()));
        } else if (type == SIFResponse.class) {
            return (new SIFHeader(this.message.getSIFResponse().getSIFHeader()));
        } else if (type == SIFSubscribe.class) {
            return (new SIFHeader(this.message.getSIFSubscribe().getSIFHeader()));
        } else if (type == SIFPing.class || type == SIFSleep.class || type == SIFWakeup.class) {
            return (new SIFHeader(this.message.getSIFSystemControl().getSIFHeader()));
        } else if (type == SIFUnprovide.class) {
            return (new SIFHeader(this.message.getSIFUnprovide().getSIFHeader()));
        } else if (type == SIFHeader.class) {
            return (new SIFHeader(this.message.getSIFUnregister().getSIFHeader()));
        }
        log.error("call to getHeader failed");
        return null;

    }

    /**
     * Sets the SIFHeader encapsulated in this message
     * @param value the new sif header for this message
     */
    public void setSIFHeader(SIFHeader value) {

        Class type = this.getClass();
        if (type == SIFAck.class) {
            this.message.getSIFAck().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        } else if (type == SIFEvent.class) {
            this.message.getSIFEvent().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        } else if (type == SIFProvide.class) {
            this.message.getSIFProvide().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        } else if (type == SIFRegister.class) {
            this.message.getSIFRegister().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        } else if (type == SIFRequest.class) {
            this.message.getSIFRequest().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        } else if (type == SIFResponse.class) {
            this.message.getSIFResponse().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        } else if (type == SIFSubscribe.class) {
            this.message.getSIFSubscribe().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        } else if (type == SIFPing.class || type == SIFSleep.class || type == SIFWakeup.class) {
            this.message.getSIFSystemControl().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        } else if (type == SIFUnprovide.class) {
            this.message.getSIFUnprovide().setSIFHeader((com.ozi.sif.objects.SIFHeader) value.getSIFObject());
        }


    }
}
